'use strict';

angular.module('starter.core', [])
    .factory('$faPlatform', function ($window, $faAPI, $rootScope) {

        var _ua = $window.navigator.userAgent,
            _host = $window.location.host,
            platform = {};

        var host = [domainname];

        function prdCheck(elem) {
            return elem === _host;
        }
        
        platform.prd = host.some(prdCheck);
        platform.android = _ua.match(/Android/i) === null ? false : true;
        platform.iPhone = _ua.match(/iPhone/i) === null ? false : true;
        platform.iPad = _ua.match(/iPad/i) === null ? false : true;
        platform.iPod = _ua.match(/iPod/i) === null ? false : true;
        platform.winPhone = _ua.match(/Windows Phone/i) === null ? false : true;
        platform.weChat = _ua.match(/micromessenger/i) === null ? false : true;
        platform.APP = _ua.match(/superfa/i) === null ? false : true;
        platform.IOS = platform.iPad || platform.iPhone;
        platform.IOSAPP = platform.IOS && platform.APP;
        platform.androidAPP = platform.android && platform.APP;
        platform.touchDevice = 'ontouchstart' in window;
        platform.newIOSAPP = false;
        platform.newAndroidAPP = false;

        document.addEventListener("deviceready", function () {
            if (typeof(device) != 'undefined') {
                // alert(device.platform);
                if (device.platform.toLowerCase() == 'ios') {
                    platform.newIOSAPP = true;
                    platform.IOSAPP = true;

                    $rootScope.newIOSAPP = true;
                } else if (device.platform.toLowerCase() == 'android') {
                    platform.newAndroidAPP = true;
                    platform.androidAPP = true;

                    $rootScope.newAndroidAPP = true;
                }
            }

            //cordova.exec(
            //    function (success) {
            //        platform.deviceAlias = success;
            //        try {
            //            $faAPI.user.setJpushAlias({jpush_alias: success || ''}).then(function (json) {
            //                console.log(json);
            //            });
            //        } catch (err) {
            //            alert(err);
            //        }
            //
            //
            //    },
            //    function (error) {
            //        alert(error);
            //    }, "MyPlugin", "getRegistrationId", []
            //);
        }, false);

        return platform;
    })
    .factory('$faUtil', function ($window, $location, $faCookies) {

        var util = {};

        var isObject = util.isObject = angular.isObject;
        var forEach = util.forEach = angular.forEach;
        var fromJson = util.fromJson = angular.fromJson;
        var toJson = util.toJson = angular.toJson;
        var extend = util.extend = angular.extend;

        /**
         * util method
         */

            // GUID 唯一标识
        util.guid = function () {
            var s4 = function () {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            }
            return (s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4());
        };

        // cookie 获取，更新
        util.cookie = function (key, value, option) {
            if (arguments.length === 1) {
                return $faCookies(key);
            } else {
                option ? $faCookies(key, value, option) : $faCookies(key, value);
            }
        };

        util.cookie.remove = function (key, options) {
            $faCookies.expire(key, options);
        };

        // localStorage 获取 更新 删除
        util.localStorage = function (key, value) {
            return arguments.length === 1 ? util.localStorage.get(key) : util.localStorage.put(key, value);
        };
        util.localStorage.get = function (key) {
            var _val = $window.localStorage && $window.localStorage.getItem(key);
            return _val && _val.indexOf('{') !== -1 ? fromJson(_val) : _val;
        };

        util.localStorage.remove = function (key) {
            $window.localStorage && $window.localStorage.removeItem(key);
        };

        util.localStorage.put = function (key, value) {
            util.localStorage.remove(key);
            value = value && isObject(value) ? toJson(value) : value;
            $window.localStorage && $window.localStorage.setItem(key, value);
        };


        // 序列化 JSON 对象为请求参数
        util.serialize = function (params) {
            var _str;

            forEach(params, function (val, key) {
                val = $window.encodeURIComponent(val);
                _str = _str ? _str + '&' + key + '=' + val : key + '=' + val;
            });

            return _str;
        };

        // svg 扇形通过角度获取点的坐标
        util.polarToCartesian = function (centerX, centerY, radius, angleInDegrees) {
            var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;
            return {
                x: centerX + (radius * Math.cos(angleInRadians)),
                y: centerY + (radius * Math.sin(angleInRadians))
            };
        };

        return util;
    })
    .factory('$faModal', function ($ionicModal, $faUtil, $state, $q) {

        function Modal(templateUrl, scope, obj) {
            this.data = {};
            this.scope = scope;
            this.templateUrl = templateUrl || '';
            obj && $faUtil.extend(this, obj);
        }

        Modal.prototype.promise = function () {

            var self = this;

            if (self.modal) {
                return $q.when();
            } else {

                self.modal = 'unique';

                return $ionicModal.fromTemplateUrl(self.templateUrl, {
                    scope: self.scope,
                    backdropClickToClose: false
                }).then(function (modal) {
                    self.modal = modal;
                });
            }
        };

        Modal.prototype.initialize = function () {
        };
        Modal.prototype.over = function () {
        };

        Modal.prototype.clear = function (key) {
            this.data[key] = '';
        };

        Modal.prototype.show = function () {
            var self = this;
            self.initialize();
            self.promise().then(function () {
                self.modal.show();
            });
        };

        Modal.prototype.hide = function () {
            var self = this;
            self.over();
            if (self.modal) {
                self.modal.remove().then(function () {
                    self.modal = null;
                });
            }

        };

        return function (name, templateUrl, scope, obj) {
            scope.modal = scope.modal || {};
            scope.modal[name] = function (data) {

                if (!scope[name]) {
                    scope[name] = new Modal(templateUrl, scope, obj);
                }

                if (data) {
                    $faUtil.extend(scope[name].data, data);
                }
                //modal函数回调，适用于登录
                if (typeof(data) == 'function') {
                    scope[name].mcallback = function (param) {
                        data(param)
                    };

                }

                scope[name].show();
            }
        };
    })
    .factory('$faLoading', function ($ionicLoading) {

        return {
            show: function () {
                $ionicLoading.show({
                    template: '<ion-spinner class="spinner spinner-ios"></ion-spinner>'
                });
            },
            hide: function () {
                $ionicLoading.hide();
            }
        };
    })
    .service('$faUploader', function () {

        /*jshint validthis: true */

        var self = this;
        self.files = [];
        self.options = {};
        self.activeUploads = 0;

        // $log.info('uiUploader loaded');

        function addFiles(files) {
            for (var i = 0; i < files.length; i++) {
                self.files.push(files[i]);
            }
        }

        function getFiles() {
            return self.files;
        }

        function startUpload(options) {
            self.options = options;
            for (var i = 0; i < self.files.length; i++) {
                if (self.activeUploads == self.options.concurrency) {
                    break;
                }
                if (self.files[i].active)
                    continue;
                ajaxUpload(self.files[i], self.options.url);
            }
        }

        function removeFile(file) {
            self.files.splice(self.files.indexOf(file), 1);
        }

        function removeAll() {
            self.files.splice(0, self.files.length);
        }

        return {
            addFiles: addFiles,
            getFiles: getFiles,
            files: self.files,
            startUpload: startUpload,
            removeFile: removeFile,
            removeAll: removeAll
        };

        function getHumanSize(bytes) {
            var sizes = ['n/a', 'bytes', 'KiB', 'MiB', 'GiB', 'TB', 'PB', 'EiB', 'ZiB', 'YiB'];
            var i = +Math.floor(Math.log(bytes) / Math.log(1024));
            return (bytes / Math.pow(1024, i)).toFixed(i ? 1 : 0) + ' ' + sizes[isNaN(bytes) ? 0 : i + 1];
        }

        function ajaxUpload(file, url) {
            var xhr, formData, prop, data = '',
                key = '' || 'file';
            self.activeUploads += 1;
            file.active = true;
            xhr = new window.XMLHttpRequest();
            formData = new window.FormData();
            xhr.open('POST', url);

            // Triggered when upload starts:
            xhr.upload.onloadstart = function () {
            };

            // Triggered many times during upload:
            xhr.upload.onprogress = function (event) {
                if (!event.lengthComputable) {
                    return;
                }
                // Update file size because it might be bigger than reported by
                // the fileSize:
                //$log.info("progres..");
                //console.info(event.loaded);
                file.loaded = event.loaded;
                file.humanSize = getHumanSize(event.loaded);
                self.options.onProgress(file);
            };

            // Triggered when upload is completed:
            xhr.onload = function () {
                self.activeUploads -= 1;
                startUpload(self.options);
                self.options.onCompleted(file, xhr.responseText);
            };

            // Triggered when upload fails:
            xhr.onerror = function () {
            };

            // Append additional data if provided:
            if (data) {
                for (prop in data) {
                    if (data.hasOwnProperty(prop)) {
                        formData.append(prop, data[prop]);
                    }
                }
            }

            // Append file data:
            formData.append(key, file, file.name);

            // Initiate upload:
            xhr.send(formData);

            return xhr;
        }
    })
    .factory('$faShake', function () {

        function Shake(options) {
            //feature detect
            this.hasDeviceMotion = 'ondevicemotion' in window;

            this.options = {
                threshold: 15, //default velocity threshold for shake to register
                timeout: 1000 //default interval between events
            };

            if (typeof options === 'object') {
                for (var i in options) {
                    if (options.hasOwnProperty(i)) {
                        this.options[i] = options[i];
                    }
                }
            }

            //use date to prevent multiple shakes firing
            this.lastTime = new Date();

            //accelerometer values
            this.lastX = null;
            this.lastY = null;
            this.lastZ = null;

            //create custom event
            if (typeof document.CustomEvent === 'function') {
                this.event = new document.CustomEvent('shake', {
                    bubbles: true,
                    cancelable: true
                });
            } else if (typeof document.createEvent === 'function') {
                this.event = document.createEvent('Event');
                this.event.initEvent('shake', true, true);
            } else {
                return false;
            }
        }

        //reset timer values
        Shake.prototype.reset = function () {
            this.lastTime = new Date();
            this.lastX = null;
            this.lastY = null;
            this.lastZ = null;
        };

        //start listening for devicemotion
        Shake.prototype.start = function () {
            this.reset();
            if (this.hasDeviceMotion) {
                window.addEventListener('devicemotion', this, false);
            }
        };

        //stop listening for devicemotion
        Shake.prototype.stop = function () {
            if (this.hasDeviceMotion) {
                window.removeEventListener('devicemotion', this, false);
            }
            this.reset();
        };

        //calculates if shake did occur
        Shake.prototype.devicemotion = function (e) {
            var current = e.accelerationIncludingGravity;
            var currentTime;
            var timeDifference;
            var deltaX = 0;
            var deltaY = 0;
            var deltaZ = 0;

            if ((this.lastX === null) && (this.lastY === null) && (this.lastZ === null)) {
                this.lastX = current.x;
                this.lastY = current.y;
                this.lastZ = current.z;
                return;
            }

            deltaX = Math.abs(this.lastX - current.x);
            deltaY = Math.abs(this.lastY - current.y);
            deltaZ = Math.abs(this.lastZ - current.z);

            if (((deltaX > this.options.threshold) && (deltaY > this.options.threshold)) || ((deltaX > this.options.threshold) && (deltaZ > this.options.threshold)) || ((deltaY > this.options.threshold) && (deltaZ > this.options.threshold))) {
                //calculate time in milliseconds since last shake registered
                currentTime = new Date();
                timeDifference = currentTime.getTime() - this.lastTime.getTime();

                if (timeDifference > this.options.timeout) {
                    window.dispatchEvent(this.event);
                    this.lastTime = new Date();
                }
            }

            this.lastX = current.x;
            this.lastY = current.y;
            this.lastZ = current.z;

        };

        //event handler
        Shake.prototype.handleEvent = function (e) {
            if (typeof(this[e.type]) === 'function') {
                return this[e.type](e);
            }
        };


        return Shake;
    })
    .factory('$faAPI', function ($http, $q, $timeout, $state, $rootScope, $cacheFactory, $ionicConfig, $faPopup, $faMAP, $faUtil, $faLoading, $location) {

        var _get, _create, _init;

        /*var hostName = 'jincs';
        if (window && (window.location.host.indexOf("licaishi.superfa.cn") < 0)) {
            hostName = 'jinceshi'
        }*/

        //APITYPE  ---API 请求类别
        var api = {
            version: '1.2.0',
            prefix: reqUrl + '/' + APITYPE + '/api',
            obstruct: $cacheFactory('apiObstruct')
        };

        _get = function (url, params, options) {

            var d = $q.defer(),
                config = {
                    method: 'GET',
                    url: url,
                    params: $faUtil.extend(params, {
                        _pt: 'wap'
                    }),                    cache: options ? options.cache : false
                },
                paramStr = $faUtil.serialize(params),
                cacheKey,
                options = options || {};

            if (!(options.flag !== undefined && !options.flag)) {
                var loading = $timeout(function () {
                    $faLoading.show();
                }, 1000)
            }

            function hideLoading() {
                $timeout.cancel(loading);
                $faLoading.hide();
            }

            cacheKey = url + paramStr;

            if (!config.cache) {
                delete config.cache
            }

            if (api.obstruct.get(cacheKey)) {

                var data = {
                    statusCode: "10001",
                    status: "ERROR"
                };

                hideLoading();

                d.reject(data);

                return d.promise;
            }

            api.obstruct.put(cacheKey, true);

            $http(config)
                .success(function (data, status, headers, config) {

                    hideLoading();

                    //alert(JSON.stringify(data))

                    if (data.statusCode === '0000') {
                        d.resolve(data.attributes);
                    } else {

                        if (data.statusCode === '2001') {

                            // 未登录，非法调用接口

                            $rootScope.user.info.isLogin = false;




                              //$rootScope.modal.login && $rootScope.modal.login();
                            if(($rootScope.newIOSAPP||$rootScope.newAndroidAPP) && $location.path()!='/') {
                                $rootScope.modal.login();//app打包时使用
                            }

                        } else {
                            if (options.NEA) {
                            } else {
                                if($faMAP.statusCode[data.statusCode] != undefined && $faMAP.statusCode[data.statusCode]!=null && $faMAP.statusCode[data.statusCode]!='') {

                                    if(data.statusCode=='2011') {
                                        d.resolve(data);
                                    }else if(data.statusCode=='2002'){
                                        //参数缺失 - 苹果上架审核<不通过>
                                    }else{
                                        $faPopup.alert({
                                            title: $faMAP.statusCode[data.statusCode]
                                        });
                                    }
                                }
                            }
                        }

                        d.reject(data);
                    }

                    $timeout(function () {
                        api.obstruct.put(cacheKey, false);
                    }, 500);

                })
                .error(function (data, status, headers, config) {
                    // $faPopup.alert({
                    //     title: '接口出错'
                    // });
                    hideLoading();

                    d.notify(data);
                    api.obstruct.put(cacheKey, false);

                    if (status == '504') {
                        $faPopup.alert({
                            title: '链接超时，请检查你的网络！'
                        });
                    }
                });

            return d.promise;
        };

        _create = function (obj, name, url, prefix) {

            var _prefix, _url;

            api[obj] = api[obj] || {};
            _prefix = prefix || '';
            _url = _prefix + url;

            api[obj][name] = function (params, options) {
                var _params;
                _params = params || {};
                return options ? _get(_url, _params, options) : _get(_url, _params);
            };
        };

        _init = function () {
            $faUtil.forEach($faMAP.api, function (val, key) {
                $faUtil.forEach(val, function (v, k) {
                    _create(key, k, v, api.prefix);
                });
            });
        };

        _init();

        // Public api here
        return api;
    })
    .factory('$faWechat', function ($window, $timeout, $location, $rootScope, $faAPI, $faPlatform) {

        function WeChat() {
            this.status = 0;
            this.ready = false;
            this.init = false;
            this.api = {};
            this.jsApiList = ['onMenuShareTimeline', 'onMenuShareAppMessage', 'chooseImage', 'uploadImage'];
        }

        WeChat.prototype.create = function (name) {

            var self = this;

            if ($faPlatform.weChat) {

                self.api[name] = function (data) {

                    var _f = function () {
                        if (self.ready) {
                            $window.wx[name](data);
                        } else {
                            $timeout(_f, 500);
                        }
                    }

                    if (!self.init) {
                        self.initialize();
                    }

                    _f();
                };

            } else {
                self.api[name] = function (data) {

                }
            }
        }

        WeChat.prototype.initialize = function () {

            var self = this;

            self.init = true;

            if ($faPlatform.weChat) {

                // 微信配置
                //2016/12/26. up 微信二次分享
                $faAPI.wechat.shareConfig({
                    requestUrl: $window.encodeURIComponent($location.absUrl())
                }, {
                    cache: false
                }).then(function (data) {

                    var conf = data.dto;

                    $window.wx.config({
                        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
                        appId: conf.appId, // 必填，公众号的唯一标识
                        timestamp: conf.timestamp, // 必填，生成签名的时间戳
                        nonceStr: conf.nonceStr, // 必填，生成签名的随机串
                        signature: conf.signature, // 必填，签名，见附录1
                        jsApiList: self.jsApiList // 必填，需要使用的JS接口列表，所有JS接口列表见附录2
                    });

                    $window.wx.ready(function () {
                        self.ready = true;
                    });

                    $window.wx.error(function (res) {
                        self.status = 1;
                    });

                });
            }
        }


        var wechat = new WeChat();

        wechat.create('onMenuShareTimeline');
        wechat.create('onMenuShareAppMessage');
        wechat.create('chooseImage');
        wechat.create('uploadImage');
        return wechat;
    })
    .factory('$faPopup', function ($ionicPopup) {

        var canAlert = true;
        var canConfirm = true;

        return {
            alert: function (obj) {

                if (canAlert) {
                    obj.okText = '关闭';//改变所有弹框确认子语
                    obj.okType= 'button-coltype'
                    $ionicPopup.alert(obj).then(function (res) {
                        canAlert = res;
                    });

                    canAlert = false;

                }

            },
            confirm: function (obj, callback) {
                if (canConfirm) {

                    $ionicPopup.confirm(obj).then(function (res) {
                        if (callback) {
                            callback(res);
                        }
                        canConfirm = true;
                    });

                    canConfirm = false;
                }
            }
        }
    })
    .factory('$faIOSBridge', function ($window, $document, $faAPI, $faPopup, $rootScope) {

        var bridge = {
            register: {
                wxLoginResponse: function () {
                    alert('aaa');
                }
            }
        };

        bridge.connect = function (callback) {

            if ($window.WebViewJavascriptBridge) {
                callback($window.WebViewJavascriptBridge)
            } else {
                $document[0].addEventListener('WebViewJavascriptBridgeReady', function () {
                    $window.WebViewJavascriptBridge.init();
                    callback($window.WebViewJavascriptBridge);
                }, false);
            }

        };


        bridge.connect(function (bridge) {
            bridge.registerHandler('wxLoginResponse', function (data, responseCallback) {

                var params = {
                    code: data.wx_code
                }


                $faAPI.wechat.appback(params).then(function (json) {
                    if (!!$rootScope.modal.login) {
                        $rootScope.login.update(json);
                    }
                }, function (json) {
                    $faPopup.confirm({
                        title: '尚未关联账户',
                        template: '立刻去关联金策师账户?'
                    }, function (res) {
                        if (res) {
                            $rootScope.relation.weChatBind = true;
                        } else {
                            $rootScope.relation.weChatBind = false;
                        }
                    })
                });


            });
        });


        bridge.store = function (key, value) {
            var self = this;
            value ? self.set(key, value) : self.get(key);
        };

        bridge.store.set = function (key, value) {

            var obj = {};

            obj[key] = value;

            bridge.connect(function (bridge) {
                bridge.callHandler('storeSet', obj, function (response) {
                });
            });


        };

        bridge.store.get = function (key) {

            var obj = {
                key: key
            };

            bridge.connect(function (bridge) {
                bridge.callHandler('storeGet', obj, function (response) {
                });
            });

        };

        bridge.store.remove = function (key) {

            var obj = {
                key: key
            };

            bridge.connect(function (bridge) {
                bridge.callHandler('storeRemove', obj, function (response) {
                });
            });

        };

        return bridge;
    })
    .factory('$faUser', function ($rootScope, $timeout, $state, $ionicHistory, $ionicPopup, $faUtil, $faAPI, $faMAP) {


        var user = $rootScope.user = {
            info: {}
        };

        user.needLoginUrl = /(user)|(customer)/;

        // 数据更新
        // 同时更新 localStorage 里的数据
        user.update = function (data) {
            //alert(JSON.stringify(data))
            if (data) {

                user.info = $faUtil.extend(user.info, data);

                $faUtil.localStorage('user', user.info);


            } else {
                user.getInfo();
            }
        };

        // 从服务器拉取用户信息
        user.getInfo = function () {

            $faAPI.user.info().then(function (json) {
                var _info = {};
                //add-2016/5/6，全局认证状态--nomad-使用全局变量，退出销毁
                //1.未提交认证，2.98认证中，3.99认证失败
                $rootScope.userRole = json.user.uRole;
                $rootScope.userImage = json.user.uImage;

                $rootScope.curUserRole = json.user.uRole;

                if (json.user.uRole == 1 || json.user.uRole == 98 || json.user.uRole == 99) {
                    $rootScope.userRole = 'RZ';
                } else {
                    $rootScope.userRole = 'ZC';
                }
                //if(!json.user.flagVistProjectInfo){
                //  $state.go('app.myself.certification');
                //}


                angular.forEach($faMAP.user, function (value, key) {

                    _info['isLogin'] = true;

                    if (key === 'name') {
                        _info[key] = json.user.uRealName || (json.user.faUserWechatDTO ? json.user.faUserWechatDTO.nickname : undefined) || json.user.uLoginName;
                    } else if (key === "avatar") {
                        _info[key] = (json.user.faUserWechatDTO ? json.user.faUserWechatDTO.headimgurl : undefined) || json.user.uImage;
                    } else if (key === "industry") {
                        _info[key] = json.user.authenticationDTO ? json.user.authenticationDTO.trade : undefined;
                    } else if (key === "working") {
                        _info[key] = json.user.authenticationDTO ? json.user.authenticationDTO.tradeAge : undefined;
                    } else {
                        _info[key] = json.user[value];
                    }

                });

                user.update(_info);
            }, function (json) {

                if (json.statusCode === '2001') {
                    $rootScope.userRole = 'DL';

                    //up-nomad-2016-4-13--zanshi

                    //直接跳转会引发第一次进个人，又退回来。--nomad.2016.04.14
                    //$state.go('app');
                }

            });
        };

        // 用户退出
        user.logout = function () {

            $faUtil.localStorage.remove('_token');

            $faUtil.cookie.remove('_token', {
                path: '/'
            });

            $faAPI.user.logout().then(function () {

                user.info = {
                    isLogin: false,
                    mobile: user.info.mobile
                };

                $faUtil.localStorage.remove('user');

                $faUtil.localStorage('user', user.info);
                $rootScope.userRole = null;
                //if (user.needLoginUrl.test($state.$current.name)) {

                $ionicHistory.nextViewOptions({
                    disableBack: true
                });

                $state.go('app');
                $rootScope.modal.login();
                //};

            });
        };

        // 用户状态

        user.checkStatus = function (res) {

            if (res.loginStatus === '1') {

                var _info = $faUtil.localStorage('user');

                if (_info) {
                    user.info = _info;
                    user.info.isLogin = true;
                } else {
                    user.update();
                }

            } else {
                user.info = {};
                user.info.isLogin = false;
            }
        };

        user.isCertDeny = function () {
            return user.info.role == 99;
        };

        user.isCertEmpty = function () {
            return user.info.role == 1;
        };

        user.isCertIng = function () {
            return user.info.role == 98;
        };

        user.isCertOk = function () {
            if (user.info.isLogin) {
                return !user.isCertDeny() && !user.isCertEmpty() && !user.isCertIng();
            }
            return false;
        }

        return user;
    })
    .factory('$faAndroidShare', function ($window) {
        return {
            share: function (shareData) {

                var data = angular.toJson(shareData);

                window.saveUrl.setShare(data);
            }
        }
    })
    .factory('$faShare', function ($window, $rootScope, $faUser, $location, $faPlatform, $faIOSBridge, $faAndroidShare, $faWechat) {
        /**
         * [shareModule--yuanhui]
         *
         * @param  shareData
         * {
     *   title:标题,
     *   desc:正文,
     *   imgUrl:用户头像url--(在产品分享中为产品图片地址！！！),
     *   link:链接地址
     *   type:0用户,1产品
     * }
         */

        var shareModule = {};
        var params = $location.search();
        var user = $faUser;
        var imgUrl, initData;


        //默认分享的链接地址
        var link = $location.absUrl();
        link = link.substr(0, link.indexOf('?'));
        //url兼容微信头像地址
        function initImgUrl(url) {
            var imgUrl;
            if (url.indexOf('http') != -1) {
                imgUrl = url;
            } else {
                imgUrl = $location.protocol() + '://' + $location.host() + url;
            }
            return imgUrl;
        }

        function initShareData(shareData) {

            if (!shareData.imgUrl) {
                if (params.mobile && params.name && params.avatar) {
                    //url带用户信息为二次分享
                    //第二次分享是否登录

                    if ($faUser.info.isLogin) {
                        link = link + '?share=1&name=' + (encodeURIComponent(user.info.name) || user.info.mobile || 'xxx') + '&avatar=' + encodeURIComponent(user.info.avatar) + '&mobile=' + user.info.mobile;
                        imgUrl = initImgUrl(params.avatar);

                    } else {
                        //第二次分享未登录取url中的用户信息
                        link = $location.absUrl() + '?share=1&name=' + params.name + '&avatar=' + params.avatar + '&mobile=' + params.mobile;
                        imgUrl = initImgUrl(params.avatar);
                    }

                } else {
                    //第一次分享看是否登录
                    if ($faUser.info.isLogin) {
                        link = $location.absUrl() + '?share=1&name=' + (encodeURIComponent(user.info.name) || user.info.mobile || 'xxx') + '&avatar=' + encodeURIComponent(user.info.avatar) + '&mobile=' + user.info.mobile;
                        imgUrl = initImgUrl($faUser.info.avatar);

                    } else {
                        link = $location.absUrl() + '?share=1&name=' + encodeURIComponent('金策师') + '&avatar=' + encodeURIComponent('http://static.superfa.cn/upload/bann/20150408/14284763485831.png') + '&mobile=400-855-8085';
                    }
                }
            } else {
                if (params.mobile && params.name && params.avatar) {


                    if ($faUser.info.isLogin) {
                        link = link + '?share=1&name=' + (encodeURIComponent(user.info.name) || user.info.mobile || 'xxx') + '&avatar=' + encodeURIComponent(user.info.avatar) + '&mobile=' + user.info.mobile;
                        imgUrl = shareData.imgUrl;

                    } else {
                        //第二次分享未登录取url中的用户信息
                        link = $location.absUrl() + '?share=1&name=' + params.name + '&avatar=' + params.avatar + '&mobile=' + params.mobile;
                        imgUrl = shareData.imgUrl;
                    }

                } else {
                    //第一次分享看是否登录
                    if ($faUser.info.isLogin) {
                        link = $location.absUrl() + '?share=1&name=' + (encodeURIComponent(user.info.name) || user.info.mobile || 'xxx') + '&avatar=' + encodeURIComponent(user.info.avatar) + '&mobile=' + user.info.mobile;
                        imgUrl = shareData.imgUrl;

                    } else {
                        link = $location.absUrl() + '?share=1&name=' + encodeURIComponent('金策师') + '&avatar=' + encodeURIComponent('http://static.superfa.cn/upload/bann/20150408/14284763485831.png') + '&mobile=400-855-8085';
                        imgUrl = shareData.imgUrl;
                    }
                }
            }

            shareData.imgUrl = imgUrl;
            shareData.link = link;
            return shareData
        }


        //app分享
        shareModule.share = function (shareData) {
            initData = initShareData(shareData);
            console.log(initShareData(shareData));
            if ($faPlatform.androidAPP) {
                $faAndroidShare.share(initData);
            }
            if ($faPlatform.IOSAPP) {
                $faIOSBridge.connect(function (bridge) {
                    bridge.callHandler('share', initData, function (response) {
                    });
                });
            }
        }

        //微信分享
        shareModule.wechatShare = function (shareData) {

            //微信分享朋友圈
            $faWechat.api.onMenuShareTimeline({
                title: shareData.title, // 分享标题
                link: shareData.link,//分享链接
                imgUrl: shareData.imgUrl, // 分享图标
                success: function () {
                    // 用户确认分享后执行的回调函数
                    //alert(shareData.link);
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            });
            //微信分享朋友
            $faWechat.api.onMenuShareAppMessage({
                title: shareData.title, // 分享标题
                desc: shareData.desc,//分享正文
                link: shareData.link,//分享链接
                imgUrl: shareData.imgUrl, // 分享图标
                type: 'link', // 分享类型,music、video或link，不填默认为link
                dataUrl: '', // 如果type是music或video，则要提供数据链接，默认为空
                success: function () {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            })
        };
        return shareModule;
    })
    .factory('$lfShare', function ($faWechat) {
        /**
         * [shareModule--nomad]
         *--2016/02/20/17:49
         *  红包活动分享module
         */
        //@nomad 方案一
        //Title（24字）：@你有一个来自金策师的红包
        //Discription（34字）：年过了，红包没收够？金策师不会让你的愿望落空！
        // 
        // 
        //方案二
        //    Title（24字）：拼手气OUT了！50元金策师红包，等你来！
        //Discription（34字）：验证送现金，红包赢不停！
        // 
        //方案三
        //    Title（24字）：猴赛雷！抢理财师红包，赢16年财运！
        //Discription（34字）：谁说猴年只有被耍的份，猴哥也能引领风骚！

        var shareModule = {};

        //微信分享
        shareModule.wechatShare = function (shareData, callback) {
            //var shareData = {
            //  title:'拼手气OUT了！50元金策师红包，等你来',
            //  desc:'验证送现金，红包赢不停！',
            //  link:'http://m2.superfa.cn/#/lf?sourceCode='+lfuserid,
            //  imgUrl:'http://m2.superfa.cn/upload/bann/20160229/1456733141901share.jpg'
            //};
            //微信分享朋友圈
            $faWechat.api.onMenuShareTimeline({
                title: shareData.title, // 分享标题
                link: shareData.link,//分享链接
                imgUrl: shareData.imgUrl, // 分享图标
                success: function () {
                    // 用户确认分享后执行的回调函数

                    if (callback) {
                        callback()
                    }
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            });
            //微信分享朋友
            $faWechat.api.onMenuShareAppMessage({
                title: shareData.title, // 分享标题
                desc: shareData.desc,//分享正文
                link: shareData.link,//分享链接
                imgUrl: shareData.imgUrl, // 分享图标
                type: 'link', // 分享类型,music、video或link，不填默认为link
                dataUrl: '', // 如果type是music或video，则要提供数据链接，默认为空
                success: function () {

                    // 用户确认分享后执行的回调函数
                    if (callback) {
                        callback()
                    }
                },
                cancel: function () {
                    // 用户取消分享后执行的回调函数
                }
            })
        };
        return shareModule;
    })
    .factory('$IdentityCodeValid', function () {
        return {
            /*
             根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定，公民身份号码是特征组合码，由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。
             地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
             出生日期码表示编码对象出生的年、月、日，其中年份用四位数字表示，年、月、日之间不用分隔符。
             顺序码表示同一地址码所标识的区域范围内，对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性，偶数分给女性。
             校验码是根据前面十七位数字码，按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

             出生日期计算方法。
             位的身份证编码首先把出生年扩展为4位，简单的就是增加一个19或18,这样就包含了所有1800-1999年出生的人;
             年后出生的肯定都是18位的了没有这个烦恼，至于1800年前出生的,那啥那时应该还没身份证号这个东东，⊙﹏⊙b汗...
             下面是正则表达式:
             出生日期1800-2099 (18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])
             身份证正则表达式 /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i
             位校验规则 6位地址编码+6位出生日期+3位顺序号
             位校验规则 6位地址编码+8位出生日期+3位顺序号+1位校验位

             校验位规则 公式:∑(ai×Wi)(mod 11)……………………………………(1)
             公式(1)中：
             i----表示号码字符从由至左包括校验码在内的位置序号；
             ai----表示第i位置上的号码字符值；
             Wi----示第i位置上的加权因子，其数值依据公式Wi=2^(n-1）(mod 11)计算得出。
             i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
             Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
             */
//身份证号合法性验证
//支持15位和18位身份证号
//支持地址编码、出生日期、校验位验证
            verify: function (code) {
                var city = {
                    11: "北京",
                    12: "天津",
                    13: "河北",
                    14: "山西",
                    15: "内蒙古",
                    21: "辽宁",
                    22: "吉林",
                    23: "黑龙江 ",
                    31: "上海",
                    32: "江苏",
                    33: "浙江",
                    34: "安徽",
                    35: "福建",
                    36: "江西",
                    37: "山东",
                    41: "河南",
                    42: "湖北 ",
                    43: "湖南",
                    44: "广东",
                    45: "广西",
                    46: "海南",
                    50: "重庆",
                    51: "四川",
                    52: "贵州",
                    53: "云南",
                    54: "西藏 ",
                    61: "陕西",
                    62: "甘肃",
                    63: "青海",
                    64: "宁夏",
                    65: "新疆",
                    71: "台湾",
                    81: "香港",
                    82: "澳门",
                    91: "国外 "
                };
                var tip = "";
                var pass = true;
                if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
                    tip = "身份证号格式错误";
                    pass = false;
                }
                else if (!city[code.substr(0, 2)]) {
                    tip = "地址编码错误";
                    pass = false;
                }
                else {
                    //18位身份证需要验证最后一位校验位
                    if (code.length == 18) {
                        code = code.split('');
                        //∑(ai×Wi)(mod 11)
                        //加权因子
                        var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
                        //校验位
                        var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
                        var sum = 0;
                        var ai = 0;
                        var wi = 0;
                        for (var i = 0; i < 17; i++) {
                            ai = code[i];
                            wi = factor[i];
                            sum += ai * wi;
                        }
                        var last = parity[sum % 11];
                        if (parity[sum % 11] != code[17]) {
                            tip = "校验位错误";
                            pass = false;
                        }
                    }
                }
                //if(!pass) alert(tip);
                return pass;
            }
        }
    })
    .factory('$yukuvideo', function ($faAPI) {
        var video = {};

        //初始化依赖js
        video.init = function (vid, id) {
            var player = new YKU.Player('youkuplayer', {
                styleid: '0',
                client_id: VIDEO_CLIENT_ID,
                vid: vid,
                newPlayer: true,
                show_related: false,
                password: VIDEO_PWD,
                events: {
                    onPlayStart: function () {
                        if (id) {
                            $faAPI.video.playVideo({
                                id: id
                            });
                        }

                    }
                }
            });
        };
        //播放
        //vid--优酷视频id
        //id--路演视频表id,统计
        video.play = function (vid, id) {
            if (typeof YKU == "undefined") {
                var body = document.body;
                var yuku = document.createElement('script');
                yuku.src = 'http://player.youku.com/jsapi';
                body.appendChild(yuku);
                yuku.onload = function () {
                    video.init(vid, id);
                };
                yuku.onerror = function () {
                    console.log('加载优酷依赖失败');
                };
            } else {
                video.init(vid, id);
            }

        };

        return video
    })
    .factory('$toview', function ($state) {
        return {
            go: function (type, id) {
                if (type && id) {
                    var url;
                    if (type == '01') {
                        url = 'product.simu';
                    } else if (type == '02' || type == '03' || type == '07') {
                        url = 'product.xtzgdetail';
                    } else if (type == '06') {
                        url = 'product.pevc';
                    }
                    $state.go(url, {id: id});
                } else {
                    console.log('$toview.go()--error');
                }

            }
        };
    })
    .factory('$authorize', function ($location, $window) {
        return {
            auth: function (callback) {

                this.ACAPPID = ACAPPID;
                this.ACSTATE = ACSTATE;
                this.ALLURL = 'http%3A%2F%2F' + calbackUrl + '%2F'+APITYPE+'%2Fapi%2Fwechat%2FmpbackJm';
                var urlParams = $location.search();
                var url = $location.url().replaceAll('&', 'L0L');
                if (urlParams) {
                    if (urlParams.statusCode == '0000') {//授权并登陆成功

                        if (callback) {
                            callback(false)
                        }
                    } else if (urlParams.statusCode == '2804') {//授权成功--未登录

                        if (callback) {
                            callback(true)
                        }

                    } else if (urlParams.statusCode == '2802') {
                        console.log('2802授权登录错误');
                    } else {
                        console.log('调用授权登录');
                        $window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.ACAPPID + '&redirect_uri=' + this.ALLURL + '&response_type=code&scope=snsapi_base&state=' + url + '@' + this.ACSTATE + '&connect_redirect=01#wechat_redirect';
                    }
                }

            },
            maAuth: function (callback) {
                this.ACAPPID = ACAPPID;
                this.ACSTATE = ACSTATE;//89生产，88测试
                this.ALLURL = 'http%3A%2F%2F' + calbackUrl + '%2F'+APITYPE+'%2Fapi%2Fwechat%2FmpbackNoLogin';
                var urlParams = $location.search();
                var url = $location.url().replaceAll('&', 'L0L');

                if (urlParams) {
                    if (urlParams.statusCode == '0000') {//授权并登陆成功

                        if (callback) {
                            callback(false)
                        }
                    } else if (urlParams.statusCode == '2804') {//授权成功--未登录

                        if (callback) {
                            callback(true)
                        }

                    } else if (urlParams.statusCode == '2802') {
                        console.log('2802授权登录错误');
                    } else {
                        console.log('调用授权登录');
                        $window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.ACAPPID + '&redirect_uri=' + this.ALLURL + '&response_type=code&scope=snsapi_userinfo&state=' + url + '@' + this.ACSTATE + '&connect_redirect=01#wechat_redirect';
                    }
                }

            }

        };
    })
    .factory('$focus', function ($timeout, $window) {
        //input 自动聚焦
        //ios设备不能触发，chrome,android正常
        return function (id) {
            $timeout(function () {
                var element = $window.document.getElementById(id);
                if (element)
                    element.focus();
            });
        };
    })
    .factory('$chatToken', function () {
        var token;
        var userImg;
        // 定义传递数据的setter函数
        var _setter = function (data) {
            token = data;
        };
        //定义获取数据的getter函数
        var _getter = function () {
            return token;
        };
        var _setter_img = function (data) {
            userImg = data;
        };
        //定义获取数据的getter函数
        var _getter_img = function () {
            return userImg;
        };
        // 在controller中通过调setter()和getter()方法可实现提交或获取参数的功能
        return {
            setter: _setter,
            getter: _getter,
            setter_img: _setter_img,
            getter_img: _getter_img
        };
    })
    .factory('$echartsMap', function () {
       var _initQxMap = function (id ,xAxisArr, subtext, legendArr, seriesArr) {
           var myChart = echarts.init(document.getElementById(id));
           var option = {
               title:{

                   subtext:subtext,
                   y:150

               },
               grid :{
                   x:20,
                   y:20,
                   x2:20,
                   y2:40
               },
               tooltip : {
                   show:true,
                   trigger: 'axis',
                   //formatter: "{a} <br/>{b} : {c}"
               },

               //legend: {
               //    data:legendArr
               //
               //},
               color: ['#2e3e50','#ff9a14'],
               calculable : false,

               xAxis : [
                   {
                       //show:false,
                       type : 'category',
                       boundaryGap : false,
                       data : xAxisArr
                   }
               ],
               yAxis : [
                   {
                       show:false,
                       type : 'value',
                       axisLabel : {
                           formatter: '{value}'
                       },
                       axisLine : {
                           show:false
                       }
                   }
               ],
               dataZoom: [

                   {
                       type: 'inside',
                       start: 1,
                       end: 100
                   }
               ],
               series : seriesArr
           };

           myChart.setOption(option);
       }

        return {
            initQxMap: _initQxMap
        };
    })
;


